<%-- 
    Document   : FlibaEducationView
    Created on : 09-11-2011, 09:04:19
    Author     : Filip Tvede Kastrup & Christian Morgan Andersen
    Responabel
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <%-- GLSL script .... derived from C
        this is the fragment shader!--%> <%-- fragment shader defines how to shade between vertexes--%>
        <script id="shader-fs" type="x-shader/x-fragment">
            #ifdef GL_ES
            precision highp float;
            #endif

            varying vec2 vTextureCoord;

            uniform sampler2D uSampler;

            uniform vec3 uColor;

            void main(void) {
                vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
                gl_FragColor = textureColor * vec4(uColor, 1.0);
            }
        </script>

        <%-- GLSL script .... derived from C
        this is the vertex shader--%>
        <script id="shader-vs" type="x-shader/x-vertex">
            attribute vec3 aVertexPosition;
            attribute vec2 aTextureCoord;

            <%-- uniform variables called uMVMatrix and uPMatrix 
            uniform variables can be accessed from outside the shader!
            these are extracted in initShaders--%>
            uniform mat4 uMVMatrix;
            uniform mat4 uPMatrix;
            
            varying vec2 vTextureCoord;

            void main(void) {
                gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
                vTextureCoord = aTextureCoord;
            }
        </script>
        <script type="text/javascript" src="javaScripts/glMatrix-0.9.5.min.js"></script>
        <script type="text/javascript" src="javaScripts/webgl-utils.js"></script>
        <script type="text/javascript" src="javaScripts/cubeObject.js"></script>
        <script type="text/javascript" src="javaScripts/kinetic-v2.3.2.js"></script>
        
        <script type="text/javascript">
            var gl; //global variabel - this is our connection to gl
            
            var pMatrix = mat4.create();
            var mvMatrix = mat4.create();
            var shaderProgram;
            
            var cubes = []; // global variabel that holds all 3d objects in the scene
            var cubeVertexPositionBuffer;
            var cubeVertexTextureCoordBuffers = [];
        //    var cubeVertexTextureCoordBuffer;
            var cubeTexture
            var dimension = 50;
            
            var lastTime = 0;
            
            var mvMatrixStack = [];
            
            var zoom = -15;
            var tilt = 56;
            var turn = 0//38;
            var rotZ = 0//40;
            var spin = 0;
            
            var currentlyPressedKeys = {};
            var currentlyMousePressedKey ={};
            var currentlyMousePosX;
            var currentlyMousePosY;
            
            var array = new Array();
            var arrayMax = 0;
       
                 
            function initGL() {
                try {
                    var canvas = document.getElementById("FLIBAMap-canvas"); //get the canvas from the document
                    gl = canvas.getContext("experimental-webgl"); // gl is associated with webGL in the canvas
                    gl.viewportWidth = canvas.width;
                    gl.viewportHeight = canvas.height;
                } catch (e) {
                }
                if (!gl) {
                    alert("Could not initialise WebGL, sorry :-(");
                }
            }
            
            function getShader(gl, id) {
                var shaderScript = document.getElementById(id);
                if (!shaderScript) {
                    return null;
                }
                var str = "";
                var k = shaderScript.firstChild;
                while (k) {
                    if (k.nodeType == 3) {
                        str += k.textContent;
                    }
                    k = k.nextSibling;
                }

                var shader;
                if (shaderScript.type == "x-shader/x-fragment") {
                    shader = gl.createShader(gl.FRAGMENT_SHADER);
                } else if (shaderScript.type == "x-shader/x-vertex") {
                    shader = gl.createShader(gl.VERTEX_SHADER);
                } else {
                    return null;
                }
                gl.shaderSource(shader, str);
                gl.compileShader(shader);

                if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                    alert(gl.getShaderInfoLog(shader));
                    return null;
                }
                return shader;
            }

            function initShaders() {
                var fragmentShader = getShader(gl, "shader-fs");
                var vertexShader = getShader(gl, "shader-vs");
                
                shaderProgram = gl.createProgram();
                gl.attachShader(shaderProgram, vertexShader);
                gl.attachShader(shaderProgram, fragmentShader);
                gl.linkProgram(shaderProgram);

                if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                    alert("Could not initialise shaders");
                }
                gl.useProgram(shaderProgram);

                shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
                gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

                shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
                gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

                shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
                shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
                shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
                shaderProgram.colorUniform = gl.getUniformLocation(shaderProgram, "uColor");
            }
            
            function handleLoadedTexture(texture) {
                gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
                gl.bindTexture(gl.TEXTURE_2D, texture);
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

                gl.bindTexture(gl.TEXTURE_2D, null);
            }
            
            function initTexture() {
                cubeTexture = gl.createTexture();
                cubeTexture.image = new Image();
                cubeTexture.image.onload = function () {
                    handleLoadedTexture(cubeTexture)
                }

                cubeTexture.image.src = "textures/scandinavia0.png";
            }
            
            function mvPushMatrix() {
                var copy = mat4.create();
                mat4.set(mvMatrix, copy);
                mvMatrixStack.push(copy);
            }

            function mvPopMatrix() {
                if (mvMatrixStack.length == 0) {
                    throw "Invalid popMatrix!";
                }
                mvMatrix = mvMatrixStack.pop();
            }
            
            function setMatrixUniforms() {
                gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
                gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
            }
            
            function initWorldObjects() {
                for(var i=0; i<dimension; i++){
                    for(var j=0; j<dimension; j++){
                        cubes.push(new Cube(i*dimension+j));
                    }
                }
                
            }
            
            function paintCubes() {
                for(var i=0; i<dimension; i++)
                    for(var j=0; j<dimension; j++){
                        cubes[i*dimension+j].cubeColor(array[i][j]);
                    }
            }
            
            function scaleCubes() {
                for(var i=0; i<dimension; i++)
                    for(var j=0; j<dimension; j++){
                        cubes[i*dimension+j].cubeScale(array[i][j]);
                    }
            }
            
            function degToRad(degrees) {
                return degrees * Math.PI / 180;
            }
            
            function animate() {
                var timeNow = new Date().getTime();
                if (lastTime != 0) {
                    var elapsed = timeNow - lastTime;

                    for(var i in cubes){
                        cubes[i].animate(elapsed);
                    }
                }
                lastTime = timeNow;
            }
            
            var mouseDown = false;
            var lastMouseX = null;
            var lastMouseY = null;

            var cubesRotationMatrix = mat4.create();
            mat4.identity(cubesRotationMatrix);

            function handleMouseDown(event) {
                mouseDown = true;
                lastMouseX = event.clientX;
                lastMouseY = event.clientY;
            }


            function handleMouseUp(event) {
                mouseDown = false;
            }


            function handleMouseMove(event) {
                if (!mouseDown) {
                    return;
                }
                var newX = event.clientX;
                var newY = event.clientY;

                var deltaX = newX - lastMouseX
                var newRotationMatrix = mat4.create();
                mat4.identity(newRotationMatrix);
                mat4.rotate(newRotationMatrix, degToRad(deltaX / 10), [0, 1, 0]);

                var deltaY = newY - lastMouseY;
                mat4.rotate(newRotationMatrix, degToRad(deltaY / 10), [1, 0, 0]);

                mat4.multiply(newRotationMatrix, cubesRotationMatrix, cubesRotationMatrix);

                lastMouseX = newX
                lastMouseY = newY;
            }
            
            
            function handleKeyDown(event) {
                currentlyPressedKeys[event.keyCode] = true;
            }
            
            function handleKeyUp(event) {
                currentlyPressedKeys[event.keyCode] = false;
            }
            
            function handleKeys() {
                if (currentlyPressedKeys[33]) {
                    // Page Up
                    document.getElementById("warning").innerHTML="Page Up";
                    zoom -= 0.1;
                }
                if (currentlyPressedKeys[34]) {
                    // Page Down
                    document.getElementById("warning").innerHTML="Page down";
                    zoom += 0.1;
                }
                if (currentlyPressedKeys[38]) {
                    // Up cursor key
                    document.getElementById("warning").innerHTML="up,"+tilt;
                    tilt += 2;
                }
                if (currentlyPressedKeys[40]) {
                    // Down cursor key
                    document.getElementById("warning").innerHTML="down,"+tilt;
                    tilt -= 2;
                }
                if (currentlyPressedKeys[37]) {
                    // Up cursor key
                    document.getElementById("warning").innerHTML="left,"+turn;
                    turn += 2;
                }
                if (currentlyPressedKeys[39]) {
                    // Down cursor key
                    document.getElementById("warning").innerHTML="right,"+turn;
                    turn -= 2;
                }
                if (currentlyPressedKeys[45]) {
                    // Up cursor key
                    document.getElementById("warning").innerHTML="left,"+rotZ;
                    rotZ += 2;
                }
                if (currentlyPressedKeys[46]) {
                    // Down cursor key
                    document.getElementById("warning").innerHTML="right,"+rotZ;
                    rotZ -= 2;
                }
            }
            
            function drawCube(cubeNumber){
                gl.activeTexture(gl.TEXTURE0);
                gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
                gl.uniform1i(shaderProgram.samplerUniform, 0);
                
                
                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffers[cubeNumber]);
                gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffers[cubeNumber].itemSize, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
                
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
                setMatrixUniforms();
                gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
            }
            
            function drawScene() {
                gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

                mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
                
                mat4.identity(mvMatrix);
                mat4.translate(mvMatrix, [0.0, 0.0, zoom]);
                mat4.rotate(mvMatrix, degToRad(rotZ), [0.0, 0.0, 1.0]);
                mat4.rotate(mvMatrix, degToRad(turn), [0.0, 1.0, 0.0]);
                
                mat4.rotate(mvMatrix, degToRad(tilt), [1.0, 0.0, 0.0]);
                
                mat4.multiply(mvMatrix, cubesRotationMatrix);
                
                for(var i in cubes){
                    cubes[i].draw(tilt, spin)
                }
            }
            function tick() {
                requestAnimationFrame(tick);
                handleKeys();
                //handleMouse();
                drawScene();
                getID();
               // animate();
            }
            
            function webGLStart(){
                initGL();
                initShaders();
                initCubeBuffers();
                initTexture();
                initWorldObjects();
                
                document.getElementById("results").innerHTML=arrayMax;
                
                gl.clearColor(0.3, 0.2, 0.2, 1.0); // sets the base color of the webGL... the background
                gl.enable(gl.DEPTH_TEST); // sets that object will be rendered acrodsing to distance from camera

                document.onkeydown = handleKeyDown;
                document.onkeyup = handleKeyUp;
                
             //   document.onmousedown = handleMousePressed;
             //   document.onmouseup = handleMouseReleased;
             //   document.onmousemove = handleMouseMove;
                
                document.getElementById("FLIBAMap-canvas").onmousedown = handleMouseDown;
                document.onmouseup = handleMouseUp;
                document.onmousemove = handleMouseMove;
                
                tick();
                
                
                document.getElementById("warning").innerHTML="run through!";
            }
            function getID() {
              var name = window.location.href.slice(window.location.href.indexOf('tech/') + 5);
              document.getElementById("mouseY").innerHTML=name;
            };
            
            var xmlHttp;
            
            function createXmlHttpRequest() {
                if(window.ActiveXObject) {
                    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
                else 
                    if(window.XMLHttpRequest) {
                    xmlHttp=new XMLHttpRequest();
                    }
            }
            
            function startRequest() {
              createXmlHttpRequest();
              xmlHttp.open("GET","http://localhost:8080/FlibaView/ArrayServlet" ,false)
              xmlHttp.onreadystatechange=handleStateChange;
              xmlHttp.send();

            }
            
            function handleStateChange() {
                if(xmlHttp.readyState==4) {
                    if(xmlHttp.status==200) {
                        // Generates a variable called 'array'
                          eval(xmlHttp.responseText);
                    }
                    else {
                       alert("Error loading pagen"+ xmlHttp.status +
                        ":"+xmlHttp.statusText);
                    }
                }
            }
        </script>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body onload="startRequest(); webGLStart();"  oncontextmenu="return false;">
        <h1>test</h1>
        <canvas id="FLIBAMap-canvas" style="border: none;" width="800" height="600"></canvas>
        <p id ="warning"> nothing</p>
        <p id ="warning2"> nothing</p>
        <p id ="mouseX"> nothing</p>
        <p id ="mouseY"> nothing</p>
        <p id="results"></p>
        <button onclick="paintCubes();">
            tryk og farv
        </button>
        <button onclick="scaleCubes();">
            tryk og scale
        </button>
    </body>
</html>

